package org.footito.android.data.database;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.footito.android.data.Comment;
import org.footito.android.data.Event;
import org.footito.android.data.Group;
import org.footito.android.data.Subscriber;
import org.footito.android.data.Team;
import org.footito.android.data.TeamStatus;
import org.footito.android.tools.FootitoException;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteConstraintException;
import android.net.Uri;
import android.util.Log;

public class ProviderAdapter {

	private ContentResolver contentResolver;
	private Context context;
	private ArrayList<Team> teamList;

	public ProviderAdapter(Context context) {
		this.context = context;
		this.contentResolver = context.getContentResolver();
	}

	public Cursor getAllEventsCursor() {
		return contentResolver.query(FootitoProvider.CONTENT_URI_EVENTS, null, null, null, null);
	}

	public Cursor getAllEventsCursorForTeam(int teamId) {
		String selection = DatabaseAdapter.REQUEST_EVENTS_BY_TEAM;
		String[] selectionArgs = { Integer.toString(teamId) };
		return contentResolver.query(FootitoProvider.CONTENT_URI_EVENTS, null, selection, selectionArgs, null);
	}

	public Event getEvent(int eventId) {
		Uri eventUri = ContentUris.withAppendedId(FootitoProvider.CONTENT_URI_EVENTS, eventId);
		Cursor c = contentResolver.query(eventUri, null, null, null, null);

		Event event = null;
		if (c.moveToFirst()) {
			event = getEventFromCursor(c);
		}

		c.close();
		return event;
	}

	public Event getEventFromCursor(Cursor cursor) {

		Event event = null;
		Team team = getTeam(cursor.getInt(FootitoProvider.COLNUM_EVENT_IDTEAM));
		if (Event.TYPE_GROUP.equals(cursor.getString(FootitoProvider.COLNUM_EVENT_TYPE))) {
			event = new Group(cursor.getInt(FootitoProvider.COLNUM_EVENT_ID), cursor.getString(FootitoProvider.COLNUM_EVENT_TYPE), team,
					cursor.getString(FootitoProvider.COLNUM_EVENT_TIMESTAMP), cursor.getString(FootitoProvider.COLNUM_EVENT_CONTENT),
					cursor.getString(FootitoProvider.COLNUM_EVENT_LINK));
		} else if (Event.TYPE_STATUS.equals(cursor.getString(FootitoProvider.COLNUM_EVENT_TYPE))) {
			event = new TeamStatus(cursor.getInt(FootitoProvider.COLNUM_EVENT_ID), cursor.getString(FootitoProvider.COLNUM_EVENT_TYPE), team,
					cursor.getString(FootitoProvider.COLNUM_EVENT_TIMESTAMP), cursor.getString(FootitoProvider.COLNUM_EVENT_CONTENT),
					cursor.getString(FootitoProvider.COLNUM_EVENT_LINK));
			if (event != null)
				loadComments((TeamStatus) event);
		}
		return event;
	}

	public List<Event> getEventList() {
		Cursor c = contentResolver.query(FootitoProvider.CONTENT_URI_EVENTS, null, null, null, null);
		ArrayList<Event> events = new ArrayList<Event>();

		if (c.moveToFirst()) {
			do {
				Event event = getEventFromCursor(c);

				if (event != null) {
					events.add(event);
				}
			} while (c.moveToNext());
		}

		c.close();

		return events;
	}

	public List<Event> getEventListFor(int teamId) {
		String selection = DatabaseAdapter.REQUEST_EVENTS_BY_TEAM;
		String[] selectionArgs = { Integer.toString(teamId) };
		Cursor c = contentResolver.query(FootitoProvider.CONTENT_URI_EVENTS, null, selection, selectionArgs, null);
		ArrayList<Event> events = new ArrayList<Event>();

		if (c.moveToFirst()) {
			do {
				Event event = getEventFromCursor(c);

				if (event != null) {
					events.add(event);
				}
			} while (c.moveToNext());
		}

		c.close();

		return events;
	}

	public Team getTeam(int idTeam) {
		for (Iterator<Team> iterator = getTeams().iterator(); iterator.hasNext();) {
			Team team = iterator.next();
			if (team.getId() == idTeam)
				return team;
		}
		return null;
	}

	/**
	 * @return the teamList
	 */
	public ArrayList<Team> getTeams() {
		if (teamList == null) {
			Cursor c = contentResolver.query(FootitoProvider.CONTENT_URI_TEAMS, null, null, null, null);

			teamList = new ArrayList<Team>();

			if (c.moveToFirst()) {
				do {
					Team team = new Team(c.getString(FootitoProvider.COLNUM_TEAM_NAME), c.getString(FootitoProvider.COLNUM_TEAM_PICTURE),
							c.getString(FootitoProvider.COLNUM_TEAM_LINK), c.getInt(FootitoProvider.COLNUM_TEAM_ID));
					teamList.add(team);

					team.loadPicture(context);

				} while (c.moveToNext());
			}

			c.close();
		}
		return teamList;
	}

	public Uri insertComment(int commentId, int commentIdEvent, String commentContent, int commentIdTeam) throws FootitoException {
		if (commentId < 0 || commentIdEvent < 0 || commentContent == null || commentIdTeam < 0)
			throw new FootitoException("Data not completed");
		ContentValues initialValues = new ContentValues();
		initialValues.put(DatabaseAdapter.COL_COMMENT_ID, commentId);
		initialValues.put(DatabaseAdapter.COL_COMMENT_CONTENT, commentContent);
		initialValues.put(DatabaseAdapter.COL_COMMENT_IDTEAM, commentIdTeam);
		initialValues.put(DatabaseAdapter.COL_COMMENT_IDEVENT, commentIdEvent);

		Uri res = null;
		try {
			res = contentResolver.insert(FootitoProvider.CONTENT_URI_COMMENTS, initialValues);
		} catch (Exception e) {
			Log.e("SQL Error", e.getMessage() + " for comment " + commentId);
		}

		return res;
	}

	public Uri insertEvent(int id, String content, int teamId, String link, String timestamp, String type) throws FootitoException {
		if (id < 0 || teamId < 0 || content == null || timestamp == null)
			throw new FootitoException("Data not completed");

		ContentValues initialValues = new ContentValues();
		initialValues.put(DatabaseAdapter.COL_EVENT_ID, id);
		initialValues.put(DatabaseAdapter.COL_EVENT_CONTENT, content);
		initialValues.put(DatabaseAdapter.COL_EVENT_IDTEAM, teamId);
		initialValues.put(DatabaseAdapter.COL_EVENT_LINK, link);
		initialValues.put(DatabaseAdapter.COL_EVENT_TIMESTAMP, timestamp);
		initialValues.put(DatabaseAdapter.COL_EVENT_TYPE, type);

		Uri res = null;
		try {
			res = contentResolver.insert(FootitoProvider.CONTENT_URI_EVENTS, initialValues);
			return res;
		} catch (SQLException e) {
			Log.e("SQL Error", e.getMessage() + " for event " + id);
			// e.printStackTrace();
		}

		return res;
	}

	public Uri insertSubscriber(int id, int idEvent, int idTeam) {
		ContentValues initialValues = new ContentValues();
		initialValues.put(DatabaseAdapter.COL_SUBSCRIBER_ID, id);
		initialValues.put(DatabaseAdapter.COL_SUBSCRIBER_IDTEAM, idTeam);
		initialValues.put(DatabaseAdapter.COL_SUBSCRIBER_IDEVENT, idEvent);
		try {
			Uri res = contentResolver.insert(FootitoProvider.CONTENT_URI_SUBSCRIBERS, initialValues);

			return res;
		} catch (SQLException e) {
			Log.e("SQL Error", e.getMessage() + " for subs " + id);
			// e.printStackTrace();
		}

		return null;

	}

	public Uri insertTeam(int id, String name, String picture, String link) throws FootitoException {
		if (id < 0 || name == null || picture == null)
			throw new FootitoException("Data not completed");
		ContentValues initialValues = new ContentValues();
		initialValues.put(DatabaseAdapter.COL_TEAM_ID, id);
		initialValues.put(DatabaseAdapter.COL_TEAM_LINK, link);
		initialValues.put(DatabaseAdapter.COL_TEAM_NAME, name);
		initialValues.put(DatabaseAdapter.COL_TEAM_PICTURE, picture);
		try {
			Uri res = contentResolver.insert(FootitoProvider.CONTENT_URI_TEAMS, initialValues);
			teamList = null;
			return res;
		} catch (SQLException e) {
			Log.e("SQL Error", e.getMessage() + " for team " + id);
			// e.printStackTrace();
		} catch (Exception e) {
			Log.e("Exception", e.getClass().toString() + ": " + e.getMessage());
		}

		return null;

	}

	public void loadComments(TeamStatus event) {
		String selection = DatabaseAdapter.REQUEST_COMS_BY_EVENT;
		String[] selectionArgs = { Integer.toString(event.getId()) };
		Cursor c = contentResolver.query(FootitoProvider.CONTENT_URI_COMMENTS, null, selection, selectionArgs, null);

		if (c.moveToFirst()) {
			do {
				Team team = getTeam(c.getInt(FootitoProvider.COLNUM_COMMENT_IDTEAM));
				Comment comment = new Comment(c.getInt(FootitoProvider.COLNUM_COMMENT_ID), c.getString(FootitoProvider.COLNUM_COMMENT_CONTENT), team,
						event);
				event.addComment(comment);
			} while (c.moveToNext());
		}

		c.close();
	}

	public void loadSubscribers(Group event) {
		String selection = DatabaseAdapter.REQUEST_SUBS_BY_EVENT;
		String[] selectionArgs = { Integer.toString(event.getId()) };
		Cursor c = contentResolver.query(FootitoProvider.CONTENT_URI_SUBSCRIBERS, null, selection, selectionArgs, null);

		if (c.moveToFirst()) {
			do {
				Subscriber sub = new Subscriber(event, getTeam(c.getInt(FootitoProvider.COLNUM_SUBSCRIBER_IDTEAM)));
				event.addSubscriber(sub);
			} while (c.moveToNext());
		}

		c.close();
	}
}
